<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Blockly Playground
    </title>
    <!-- This script loads uncompressed when on localhost and loads
compressed when it is being hosted or on Internet Explorer.  -->
    <script src="custom_renderer.js"></script>
    <script>
      var BLOCKLY_BOOTSTRAP_OPTIONS = {
        additionalScripts: [
          'msg/messages.js',
          'tests/playgrounds/screenshot.js',
          'node_modules/@blockly/dev-tools/dist/index.js',
        ],
      }
    </script>
    <script src="bootstrap.js">
    </script>
    <script type=module>
      // Wait for Blockly to finish loading.
      import './bootstrap_done.mjs';
      const IS_UNCOMPRESSED = !window.bootstrapInfo.compressed;
      // See bootstrap.js
      var workspace = null;
      function start() {
        setBackgroundColour();
        // Parse the URL arguments.
        var match = location.search.match(/dir=([^&]+)/);
        var rtl = match && match[1] == 'rtl';
        document.forms.options.elements.dir.selectedIndex = Number(rtl);
        var toolbox = getToolboxElement();
        setToolboxDropdown();
        match = location.search.match(/side=([^&]+)/);
        var autoimport = !!location.search.match(/autoimport=([^&]+)/);
        // Create main workspace.
        workspace = Blockly.inject('blocklyDiv',
                                   {
          comments: true,
          collapse: true,
          disable: true,
          grid:
          {
            spacing: 25,
            length: 3,
            colour: '#ccc',
            snap: true
          }
          ,
          horizontalLayout: false,
          maxBlocks: Infinity,
          maxInstances: {
            'test_basic_limit_instances': 3}
          ,
          maxTrashcanContents: 256,
          media: '../media/',
          oneBasedIndex: true,
          readOnly: false,
          rtl: rtl,
          move: {
            scrollbars: true,
            drag: true,
            wheel: false,
          }
          ,
          toolbox: toolbox,
          toolboxPosition: 'start',
          renderer: 'geras',
          zoom:
          {
            controls: true,
            wheel: true,
            startScale: 1.0,
            maxScale: 4,
            minScale: 0.25,
            scaleSpeed: 1.1
          }
        }
                                  );
        initToolbox(workspace);
        workspace.configureContextMenu = configureContextMenu;
        // Restore previously displayed text.
        if (sessionStorage) {
          var text = sessionStorage.getItem('textarea');
          if (text) {
            document.getElementById('importExport').value = text;
          }
          // Restore event logging state.
          var logMainEventsState = sessionStorage.getItem('logEvents');
          logEvents(Boolean(Number(logMainEventsState)));
          var logToolboxFlyoutEventsState = sessionStorage.getItem('logFlyoutEvents');
          logFlyoutEvents(Boolean(Number(logToolboxFlyoutEventsState)));
        }
        else {
          // MSIE 11 does not support sessionStorage on file:// URLs.
          logEvents(false);
        }
        taChange();
        if (autoimport) {
          load();
        }
        addEventHandlers();
      }
      function setBackgroundColour() {
        // Set background colour to differentiate between compressed and uncompressed mode.
        if (IS_UNCOMPRESSED) {
          document.body.style.backgroundColor = '#d6d6ff';
          // Familiar lilac.
        }
        else {
          document.body.style.backgroundColor = '#60fcfc';
          // Unfamiliar blue.
        }
      }
      function getToolboxSuffix() {
        var match = location.search.match(/toolbox=([^&]+)/);
        // Default to the basic toolbox with categories and untyped variables,
        // but override that if the toolbox type is set in the URL.
        return (match ? match[1] : 'categories');
      }
      function getToolboxElement() {
        var toolboxSuffix = getToolboxSuffix();
        if (toolboxSuffix == 'test-blocks') {
          if (typeof window.toolboxTestBlocks !== 'undefined') {
            return toolboxTestBlocks;
          }
          else {
            alert('You need to run \'npm install\' in order to use the test blocks.');
            toolboxSuffix = 'categories';
          }
        }
        // The three possible values are: "simple", "categories",
        // "categories-typed-variables".
        return document.getElementById('toolbox-' + toolboxSuffix);
      }
      function setToolboxDropdown() {
        var toolboxNames = [
          'toolbox-categories',
          'toolbox-categories-typed-variables',
          'toolbox-simple',
          'toolbox-test-blocks'
        ];
        var toolboxSuffix = getToolboxSuffix();
        document.forms.options.elements.toolbox.selectedIndex =
          toolboxNames.indexOf('toolbox-' + toolboxSuffix);
      }
      function initToolbox(workspace) {
        var toolboxSuffix = getToolboxSuffix();
        if (toolboxSuffix == 'test-blocks' &&
            typeof window.toolboxTestBlocksInit !== 'undefined') {
          toolboxTestBlocksInit(workspace);
        }
      }
      function saveXml() {
        var output = document.getElementById('importExport');
        var xml = Blockly.Xml.workspaceToDom(workspace);
        output.value = Blockly.Xml.domToPrettyText(xml);
        output.focus();
        output.select();
        taChange();
      }
      function saveJson() {
        var output = document.getElementById('importExport');
        var state = Blockly.serialization.workspaces.save(workspace);
        output.value = JSON.stringify(state, null, 2);
        output.focus();
        output.select();
        taChange();
      }
      function load() {
        var input = document.getElementById('importExport');
        if (!input.value) {
          return;
        }
        var valid = saveIsValid(input.value);
        if (valid.json) {
          var state = JSON.parse(input.value);
          Blockly.serialization.workspaces.load(state, workspace);
        }
        else if (valid.xml) {
          var xml = Blockly.Xml.textToDom(input.value);
          Blockly.Xml.domToWorkspace(xml, workspace);
        }
        taChange();
      }
      function toCode(lang) {
        var generator = ({
          'JavaScript': javascriptGenerator,
          'Python': pythonGenerator,
          'PHP': phpGenerator,
          'Lua': luaGenerator,
          'Dart': dartGenerator,
        }
                        )[lang];
        var output = document.getElementById('importExport');
        output.value = generator.workspaceToCode(workspace);
        taChange();
      }
      // Disable the "Load" button if the save state is invalid.
      // Preserve text between page reloads.
      function taChange() {
        var textarea = document.getElementById('importExport');
        if (sessionStorage) {
          sessionStorage.setItem('textarea', textarea.value);
        }
        var valid = saveIsValid(textarea.value);
        document.getElementById('import').disabled = !valid.json && !valid.xml;
      }
      function saveIsValid(save) {
        var validJson = true;
        try {
          JSON.parse(save);
        }
        catch (e) {
          validJson = false;
        }
        var validXml = true
        try {
          Blockly.Xml.textToDom(save);
        }
        catch (e) {
          validXml = false;
        }
        return {
          json: validJson,
          xml: validXml
        }
      }
      function logEvents(state) {
        var checkbox = document.getElementById('logCheck');
        checkbox.checked = state;
        if (sessionStorage) {
          sessionStorage.setItem('logEvents', Number(state));
        }
        if (state) {
          workspace.addChangeListener(logger);
        }
        else {
          workspace.removeChangeListener(logger);
        }
      }
      function logFlyoutEvents(state) {
        var checkbox = document.getElementById('logFlyoutCheck');
        checkbox.checked = state;
        if (sessionStorage) {
          sessionStorage.setItem('logFlyoutEvents', Number(state));
        }
        var flyoutWorkspace = workspace.getFlyout().getWorkspace();
        if (state) {
          flyoutWorkspace.addChangeListener(logger);
        }
        else {
          flyoutWorkspace.removeChangeListener(logger);
        }
      }
      function configureContextMenu(menuOptions, e) {
        var screenshotOption = {
          text: 'Download Screenshot',
          enabled: workspace.getTopBlocks().length,
          callback: function() {
            downloadScreenshot(workspace);
          }
        };
        menuOptions.push(screenshotOption);
        // Adds a default-sized workspace comment to the workspace.
        menuOptions.push(Blockly.ContextMenu.workspaceCommentOption(workspace, e));
      }
      function logger(e) {
        console.log(e);
      }
      function airstrike(n) {
        var prototypes = [];
        var toolbox = getToolboxElement();
        var blocks = toolbox.getElementsByTagName('block');
        for (var i = 0, block; block = blocks[i]; i++) {
          prototypes.push(block.getAttribute('type'));
        }
        for (var i = 0; i < n; i++) {
          var prototype = prototypes[Math.floor(Math.random() * prototypes.length)];
          var block = workspace.newBlock(prototype);
          block.initSvg();
          block.getSvgRoot().setAttribute('transform', 'translate(' +
                                          Math.round(Math.random() * 450 + 40) + ', ' +
                                          Math.round(Math.random() * 600 + 40) + ')');
          block.render();
        }
      }
      function spaghetti(n) {
        var xml = spaghettiXml;
        for(var i = 0; i < n; i++) {
          xml = xml.replace(/(<(statement|next)( name="DO0")?>)<\//g,
                            '$1' + spaghettiXml + '</');
        }
        xml = '<xml xmlns="https://developers.google.com/blockly/xml">' + xml + '</xml>';
        var dom = Blockly.Xml.textToDom(xml);
        console.time('Spaghetti domToWorkspace');
        Blockly.Xml.domToWorkspace(dom, workspace);
        console.timeEnd('Spaghetti domToWorkspace');
      }
      var spaghettiXml = [
        '  <block type="controls_if">',
        '    <value name="IF0">',
        '      <block type="logic_compare">',
        '        <field name="OP">EQ</field>',
        '        <value name="A">',
        '          <block type="math_arithmetic">',
        '            <field name="OP">MULTIPLY</field>',
        '            <value name="A">',
        '              <block type="math_number">',
        '                <field name="NUM">6</field>',
        '              </block>',
        '            </value>',
        '            <value name="B">',
        '              <block type="math_number">',
        '                <field name="NUM">7</field>',
        '              </block>',
        '            </value>',
        '          </block>',
        '        </value>',
        '        <value name="B">',
        '          <block type="math_number">',
        '            <field name="NUM">42</field>',
        '          </block>',
        '        </value>',
        '      </block>',
        '    </value>',
        '    <statement name="DO0"></statement>',
        '    <next></next>',
        '  </block>'].join('\n');
      function jsoSpaghetti(n) {
        var str = spaghettiJs;
        for (var i = 0; i < n; i++) {
          str = str.replace(/{}/g, `{"block":${spaghettiJs}
}`);
        }
        var obj = {
          'blocks': {
            'blocks': [
              JSON.parse(str)
            ]
          }
        };
        console.time('Spaghetti serialization');
        Blockly.serialization.workspaces.load(obj, workspace);
        console.timeEnd('Spaghetti serialization');
      }
      var spaghettiJs = JSON.stringify({
        'type': 'controls_if',
        'inputs': {
          'IF0': {
            'block': {
              'type': 'logic_compare',
              'fields': {
                'OP': 'EQ',
              }
              ,
              'inputs': {
                'A': {
                  'block': {
                    'type': 'math_arithmetic',
                    'fields': {
                      'OP': 'MULTIPLY',
                    }
                    ,
                    'inputs': {
                      'A': {
                        'block': {
                          'type': 'math_number',
                          'fields': {
                            'NUM': 6
                          }
                        }
                      }
                      ,
                      'B': {
                        'block': {
                          'type': 'math_number',
                          'fields': {
                            'NUM': 7
                          }
                        }
                      }
                    }
                  }
                }
                ,
                'B': {
                  'block': {
                    'type': 'math_number',
                    'fields': {
                      'NUM': 42
                    }
                  }
                }
              }
            }
          }
          ,
          'DO0': {
          }
        }
        ,
        'next': {
        }
      }
                                      );
      function addEventHandlers() {
        document.getElementById('save-json').addEventListener('click', saveJson);
        document.getElementById('save-xml').addEventListener('click', saveXml);
        document.getElementById('import').addEventListener('click', load);
        document.getElementById('to-code-js')
          .addEventListener('click', () => toCode('JavaScript'));
        document.getElementById('to-code-py')
          .addEventListener('click', () => toCode('Python'));
        document.getElementById('to-code-php')
          .addEventListener('click', () => toCode('PHP'));
        document.getElementById('to-code-lua')
          .addEventListener('click', () => toCode('Lua'));
        document.getElementById('to-code-dart')
          .addEventListener('click', () => toCode('Dart'));
        document.getElementById('airstrike')
          .addEventListener('click', () => airstrike(100));
        document.getElementById('spaghetti-xml')
          .addEventListener('click', () => spaghetti(8));
        document.getElementById('spaghetti-js')
          .addEventListener('click', () => jsoSpaghetti(8));
        document.getElementById('logCheck')
          .addEventListener('click', function() {
          logEvents(this.checked) }
                           );
        document.getElementById('logFlyoutCheck')
          .addEventListener('click', function() {
          logFlyoutEvents(this.checked) }
                           );
        document.getElementById('importExport').addEventListener('change', taChange);
        document.getElementById('importExport').addEventListener('keyup', taChange);
        document.getElementById('show')
          .addEventListener('click', function() {
          workspace.setVisible(true);
        }
                           );
        document.getElementById('hide')
          .addEventListener('click', function() {
          workspace.setVisible(false);
        }
                           );
      }
      // Call start().  Because this <script> has type=module, it is
      // automatically deferred, so it will not be run until after the
      // document has been parsed, but before firing DOMContentLoaded.
      start();
    </script>
    <style>
      html, body {
        height: 100%;
      }
      body {
        background-color: #fff;
        font-family: sans-serif;
        overflow: hidden;
      }
      h1 {
        font-weight: normal;
        font-size: 140%;
      }
      #blocklyDiv {
        float: right;
        height: 95%;
        width: 70%;
      }
      #importExport {
        font-family: monospace;
      }
      .ioLabel>.blocklyFlyoutLabelText {
        font-style: italic;
      }
      #blocklyDiv.renderingDebug .blockRenderDebug {
        display: block;
      }
      .playgroundToggleOptions {
        list-style: none;
        padding: 0;
      }
      .playgroundToggleOptions li {
        margin-top: 1em;
      }
      .zelos-renderer .blocklyFlyoutButton .blocklyText {
        font-size: 1.5rem;
      }
    </style>
  </head>
  <body>
    <div id="blocklyDiv">
    </div>
    <h1>Blockly Playground
    </h1>
    <p>
      <input id="show" type="button" value="Show">
    
  <input id="hide" type="button" value="Hide">
<a href="playgrounds/advanced_playground.html">Advanced
</a>
</p>
<form id="options">
  <select name="dir" onchange="document.forms.options.submit()">
    <option value="ltr">LTR
    </option>
    <option value="rtl">RTL
    </option>
  </select>
  <select name="toolbox" onchange="document.forms.options.submit()">
    <option value="categories">Categories (untyped variables)
    </option>
    <option value="categories-typed-variables">Categories (typed variables)
    </option>
    <option value="simple">Simple
    </option>
    <option value="test-blocks">Test Blocks
    </option>
  </select>
</form>
<p>
  <input id="save-json" type="button" value="Save JSON">
  <input id="save-xml" type="button" value="Save XML">
  <input type="button" value="Load" id="import">
  <br>
  <input id="to-code-js" type="button" value="To JavaScript">
  <input id="to-code-py" type="button" value="To Python">
  <input id="to-code-php" type="button" value="To PHP">
  <input id="to-code-lua" type="button" value="To Lua">
  <input id="to-code-dart" type="button" value="To Dart">
  <br>
  <textarea id="importExport" style="width: 26%; height: 12em">
  </textarea>
</p>
<p>
  Stress test: &nbsp;
  <input id="airstrike" type="button" value="Airstrike!">
  <input id="spaghetti-xml" type="button" value="Spaghetti!">
  <input id="spaghetti-js" type="button" value="JS Spaghetti!">
</p>
<ul class="playgroundToggleOptions">
  <li>
    <label for="logCheck">Log main workspace events:
    </label>
    <input type="checkbox" id="logCheck">
  </li>
  <li>
    <label for="logFlyoutCheck">Log flyout events:
    </label>
    <input type="checkbox" id="logFlyoutCheck">
  </li>
</ul>
<!-- The next three blocks of XML are sample toolboxes for testing basic
configurations.  For more information on building toolboxes, see https://developers.google.com/blockly/guides/configure/web/toolbox -->
<!-- toolbox-simple is an always-open flyout with no category menu.
Always-open flyouts are a good idea if you have a small number of blocks. -->
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-simple" style="display: none">
  <block type="controls_ifelse">
  </block>
  <block type="logic_compare">
  </block>
  <!-- <block type="control_repeat"></block> -->
  <block type="logic_operation">
  </block>
  <block type="controls_repeat_ext">
    <value name="TIMES">
      <shadow type="math_number">
        <field name="NUM">10
        </field>
      </shadow>
    </value>
  </block>
  <block type="logic_operation">
  </block>
  <block type="logic_negate">
  </block>
  <block type="logic_boolean">
  </block>
  <block type="logic_null" disabled="true">
  </block>
  <block type="logic_ternary">
  </block>
  <block type="text_charAt">
    <value name="VALUE">
      <block type="variables_get">
        <field name="VAR">text
        </field>
      </block>
    </value>
  </block>
</xml>
<!-- toolbox-categories has a category menu and an auto-closing flyout.  The
Variables category uses untyped variable blocks.
See https://developers.google.com/blockly/guides/create-custom-blocks/variables#untyped_variable_blocks for more information. -->
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-categories" style="display: none">
  <category name="Logic" categorystyle="logic_category">
    <block type="controls_if">
    </block>
    <block type="logic_compare">
    </block>
    <block type="logic_operation">
    </block>
    <block type="logic_negate">
    </block>
    <block type="logic_boolean">
    </block>
    <block type="logic_null" disabled="true">
    </block>
    <block type="logic_ternary">
    </block>
  </category>
  <category name="Loops" categorystyle="loop_category">
    <block type="controls_repeat_ext">
      <value name="TIMES">
        <shadow type="math_number">
          <field name="NUM">10
          </field>
        </shadow>
      </value>
    </block>
    <block type="controls_repeat" disabled="true">
    </block>
    <block type="controls_whileUntil">
    </block>
    <block type="controls_for">
      <value name="FROM">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="TO">
        <shadow type="math_number">
          <field name="NUM">10
          </field>
        </shadow>
      </value>
      <value name="BY">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
    </block>
    <block type="controls_forEach">
    </block>
    <block type="controls_flow_statements">
    </block>
  </category>
  <category name="Math" categorystyle="math_category">
    <block type="math_number" gap="32">
      <field name="NUM">123
      </field>
    </block>
    <block type="math_arithmetic">
      <value name="A">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="B">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_single">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">9
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_trig">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">45
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_constant">
    </block>
    <block type="math_number_property">
      <value name="NUMBER_TO_CHECK">
        <shadow type="math_number">
          <field name="NUM">0
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_round">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">3.1
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_on_list">
    </block>
    <block type="math_modulo">
      <value name="DIVIDEND">
        <shadow type="math_number">
          <field name="NUM">64
          </field>
        </shadow>
      </value>
      <value name="DIVISOR">
        <shadow type="math_number">
          <field name="NUM">10
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_constrain">
      <value name="VALUE">
        <shadow type="math_number">
          <field name="NUM">50
          </field>
        </shadow>
      </value>
      <value name="LOW">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="HIGH">
        <shadow type="math_number">
          <field name="NUM">100
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_random_int">
      <value name="FROM">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="TO">
        <shadow type="math_number">
          <field name="NUM">100
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_random_float">
    </block>
    <block type="math_atan2">
      <value name="X">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="Y">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
    </block>
  </category>
  <category name="Text" categorystyle="text_category">
    <block type="text">
    </block>
    <block type="text_multiline">
    </block>
    <block type="text_join">
    </block>
    <block type="text_append">
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <block type="text_length">
      <value name="VALUE">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_isEmpty">
      <value name="VALUE">
        <shadow type="text">
          <field name="TEXT">
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_indexOf">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">text
          </field>
        </block>
      </value>
      <value name="FIND">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_charAt">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">text
          </field>
        </block>
      </value>
    </block>
    <block type="text_getSubstring">
      <value name="STRING">
        <block type="variables_get">
          <field name="VAR">text
          </field>
        </block>
      </value>
    </block>
    <block type="text_changeCase">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_trim">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_count">
      <value name="SUB">
        <shadow type="text">
        </shadow>
      </value>
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <block type="text_replace">
      <value name="FROM">
        <shadow type="text">
        </shadow>
      </value>
      <value name="TO">
        <shadow type="text">
        </shadow>
      </value>
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <block type="text_reverse">
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <label text="Input/Output:" web-class="ioLabel">
    </label>
    <block type="text_print">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_prompt_ext">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
  </category>
  <category name="Lists" categorystyle="list_category">
    <block type="lists_create_with">
      <mutation items="0">
      </mutation>
    </block>
    <block type="lists_create_with">
    </block>
    <block type="lists_repeat">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">5
          </field>
        </shadow>
      </value>
    </block>
    <block type="lists_length">
    </block>
    <block type="lists_isEmpty">
    </block>
    <block type="lists_indexOf">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_getIndex">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_setIndex">
      <value name="LIST">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_getSublist">
      <value name="LIST">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_split">
      <value name="DELIM">
        <shadow type="text">
          <field name="TEXT">,
          </field>
        </shadow>
      </value>
    </block>
    <block type="lists_sort">
    </block>
    <block type="lists_reverse">
    </block>
  </category>
  <category name="Colour" categorystyle="colour_category">
    <block type="colour_picker">
    </block>
    <block type="colour_random">
    </block>
    <block type="colour_rgb">
      <value name="RED">
        <shadow type="math_number">
          <field name="NUM">100
          </field>
        </shadow>
      </value>
      <value name="GREEN">
        <shadow type="math_number">
          <field name="NUM">50
          </field>
        </shadow>
      </value>
      <value name="BLUE">
        <shadow type="math_number">
          <field name="NUM">0
          </field>
        </shadow>
      </value>
    </block>
    <block type="colour_blend">
      <value name="COLOUR1">
        <shadow type="colour_picker">
          <field name="COLOUR">#ff0000
          </field>
        </shadow>
      </value>
      <value name="COLOUR2">
        <shadow type="colour_picker">
          <field name="COLOUR">#3333ff
          </field>
        </shadow>
      </value>
      <value name="RATIO">
        <shadow type="math_number">
          <field name="NUM">0.5
          </field>
        </shadow>
      </value>
    </block>
  </category>
  <sep>
  </sep>
  <category name="Variables" categorystyle="variable_category" custom="VARIABLE">
  </category>
  <category name="Functions" categorystyle="procedure_category" custom="PROCEDURE">
  </category>
</xml>
<!-- toolbox-categories-typed-variables has a category menu and an
auto-closing flyout.  The Variables category uses typed variable blocks.
See https://developers.google.com/blockly/guides/create-custom-blocks/variables#typed_variable_blocks for more information. -->
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox-categories-typed-variables" style="display: none">
  <category name="Logic" categorystyle="logic_category">
    <block type="controls_if">
    </block>
    <block type="logic_compare">
    </block>
    <block type="logic_operation">
    </block>
    <block type="logic_negate">
    </block>
    <block type="logic_boolean">
    </block>
    <block type="logic_null" disabled="true">
    </block>
    <block type="logic_ternary">
    </block>
  </category>
  <category name="Loops" categorystyle="loop_category">
    <block type="controls_repeat_ext">
      <value name="TIMES">
        <shadow type="math_number">
          <field name="NUM">10
          </field>
        </shadow>
      </value>
    </block>
    <block type="controls_repeat" disabled="true">
    </block>
    <block type="controls_whileUntil">
    </block>
    <block type="controls_for">
      <value name="FROM">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="TO">
        <shadow type="math_number">
          <field name="NUM">10
          </field>
        </shadow>
      </value>
      <value name="BY">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
    </block>
    <block type="controls_forEach">
    </block>
    <block type="controls_flow_statements">
    </block>
  </category>
  <category name="Math" categorystyle="math_category">
    <block type="math_number" gap="32">
      <field name="NUM">123
      </field>
    </block>
    <block type="math_arithmetic">
      <value name="A">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="B">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_single">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">9
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_trig">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">45
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_constant">
    </block>
    <block type="math_number_property">
      <value name="NUMBER_TO_CHECK">
        <shadow type="math_number">
          <field name="NUM">0
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_round">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">3.1
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_on_list">
    </block>
    <block type="math_modulo">
      <value name="DIVIDEND">
        <shadow type="math_number">
          <field name="NUM">64
          </field>
        </shadow>
      </value>
      <value name="DIVISOR">
        <shadow type="math_number">
          <field name="NUM">10
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_constrain">
      <value name="VALUE">
        <shadow type="math_number">
          <field name="NUM">50
          </field>
        </shadow>
      </value>
      <value name="LOW">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="HIGH">
        <shadow type="math_number">
          <field name="NUM">100
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_random_int">
      <value name="FROM">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="TO">
        <shadow type="math_number">
          <field name="NUM">100
          </field>
        </shadow>
      </value>
    </block>
    <block type="math_random_float">
    </block>
    <block type="math_atan2">
      <value name="X">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
      <value name="Y">
        <shadow type="math_number">
          <field name="NUM">1
          </field>
        </shadow>
      </value>
    </block>
  </category>
  <category name="Text" categorystyle="text_category">
    <block type="text">
    </block>
    <block type="text_multiline">
    </block>
    <block type="text_join">
    </block>
    <block type="text_append">
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <block type="text_length">
      <value name="VALUE">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_isEmpty">
      <value name="VALUE">
        <shadow type="text">
          <field name="TEXT">
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_indexOf">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">text
          </field>
        </block>
      </value>
      <value name="FIND">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_charAt">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">text
          </field>
        </block>
      </value>
    </block>
    <block type="text_getSubstring">
      <value name="STRING">
        <block type="variables_get">
          <field name="VAR">text
          </field>
        </block>
      </value>
    </block>
    <block type="text_changeCase">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_trim">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_count">
      <value name="SUB">
        <shadow type="text">
        </shadow>
      </value>
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <block type="text_replace">
      <value name="FROM">
        <shadow type="text">
        </shadow>
      </value>
      <value name="TO">
        <shadow type="text">
        </shadow>
      </value>
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <block type="text_reverse">
      <value name="TEXT">
        <shadow type="text">
        </shadow>
      </value>
    </block>
    <label text="Input/Output:" web-class="ioLabel">
    </label>
    <block type="text_print">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
    <block type="text_prompt_ext">
      <value name="TEXT">
        <shadow type="text">
          <field name="TEXT">abc
          </field>
        </shadow>
      </value>
    </block>
  </category>
  <category name="Lists" categorystyle="list_category">
    <block type="lists_create_with">
      <mutation items="0">
      </mutation>
    </block>
    <block type="lists_create_with">
    </block>
    <block type="lists_repeat">
      <value name="NUM">
        <shadow type="math_number">
          <field name="NUM">5
          </field>
        </shadow>
      </value>
    </block>
    <block type="lists_length">
    </block>
    <block type="lists_isEmpty">
    </block>
    <block type="lists_indexOf">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_getIndex">
      <value name="VALUE">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_setIndex">
      <value name="LIST">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_getSublist">
      <value name="LIST">
        <block type="variables_get">
          <field name="VAR">list
          </field>
        </block>
      </value>
    </block>
    <block type="lists_split">
      <value name="DELIM">
        <shadow type="text">
          <field name="TEXT">,
          </field>
        </shadow>
      </value>
    </block>
    <block type="lists_sort">
    </block>
    <block type="lists_reverse">
    </block>
  </category>
  <category name="Colour" categorystyle="colour_category">
    <block type="colour_picker">
    </block>
    <block type="colour_random">
    </block>
    <block type="colour_rgb">
      <value name="RED">
        <shadow type="math_number">
          <field name="NUM">100
          </field>
        </shadow>
      </value>
      <value name="GREEN">
        <shadow type="math_number">
          <field name="NUM">50
          </field>
        </shadow>
      </value>
      <value name="BLUE">
        <shadow type="math_number">
          <field name="NUM">0
          </field>
        </shadow>
      </value>
    </block>
    <block type="colour_blend">
      <value name="COLOUR1">
        <shadow type="colour_picker">
          <field name="COLOUR">#ff0000
          </field>
        </shadow>
      </value>
      <value name="COLOUR2">
        <shadow type="colour_picker">
          <field name="COLOUR">#3333ff
          </field>
        </shadow>
      </value>
      <value name="RATIO">
        <shadow type="math_number">
          <field name="NUM">0.5
          </field>
        </shadow>
      </value>
    </block>
  </category>
  <sep>
  </sep>
  <category name="Variables" categorystyle="variable_category" custom="VARIABLE_DYNAMIC">
  </category>
  <category name="Functions" categorystyle="procedure_category" custom="PROCEDURE">
  </category>
</xml>
</body>
</html>